﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;
using Microsoft.CSharp.RuntimeBinder;

namespace SystemDiagramNew
{
	public static class ExtensibleStorageManager
	{
		public static Schema CreateSchema()
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.m_GUID);
			if (schema != null)
			{
				return schema;
			}
			SchemaBuilder schemaBuilder = new SchemaBuilder(ExtensibleStorageManager.m_GUID);
			schemaBuilder.SetSchemaName(ExtensibleStorageManager.m_schemaName);
			schemaBuilder.AddSimpleField("Diameter", typeof(double)).SetUnitType(0);
			schemaBuilder.AddSimpleField("StartElevation", typeof(double)).SetUnitType(0);
			schemaBuilder.AddSimpleField("EndElevation", typeof(double)).SetUnitType(0);
			schemaBuilder.AddSimpleField("LegendScale", typeof(double)).SetUnitType(0);
			return schemaBuilder.Finish();
		}

		public static void WritePipeExtensibleStorageToDetailCurve(Pipe pipe, DetailCurve curve, double legendScale)
		{
			Schema schema = ExtensibleStorageManager.CreateSchema();
			Entity entity = new Entity(schema);
			int num = (int)AssistFunc.feetToMM(pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble());
			Field field = schema.GetField("Diameter");
			entity.Set<double>(field, (double)num, (Autodesk.Revit.DB.DisplayUnitType)6);
			double num2 = pipe.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble();
			Field field2 = schema.GetField("StartElevation");
			entity.Set<double>(field2, num2, (Autodesk.Revit.DB.DisplayUnitType)6);
			double num3 = pipe.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble();
			Field field3 = schema.GetField("EndElevation");
			entity.Set<double>(field3, num3, (Autodesk.Revit.DB.DisplayUnitType)6);
			Field field4 = schema.GetField("LegendScale");
			entity.Set<double>(field4, legendScale, (Autodesk.Revit.DB.DisplayUnitType)6);
			curve.SetEntity(entity);
		}

		public static bool IsPipeDetailCurve(DetailLine line)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.m_GUID);
			Entity entity = line.GetEntity(schema);
			return entity.Schema != null;
		}

		public static bool ReadPipeExtensibleStorageFromDetailCurve(DetailCurve curve, ref int diameter, ref double startElevation, ref double endElevation, ref double legendScale)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.m_GUID);
			if (schema == null)
			{
				return false;
			}
			Entity entity = curve.GetEntity(schema);
			if (entity.Schema == null)
			{
				return false;
			}
			double num = entity.Get<double>(schema.GetField("Diameter"), (Autodesk.Revit.DB.DisplayUnitType)6);
			diameter = (int)num;
			startElevation = entity.Get<double>(schema.GetField("StartElevation"), (Autodesk.Revit.DB.DisplayUnitType)6);
			startElevation = UnitConvert.LengthToInternal(startElevation);
			endElevation = entity.Get<double>(schema.GetField("EndElevation"), (Autodesk.Revit.DB.DisplayUnitType)6);
			endElevation = UnitConvert.LengthToInternal(endElevation);
			legendScale = entity.Get<double>(schema.GetField("LegendScale"), (Autodesk.Revit.DB.DisplayUnitType)6);
			return true;
		}

		private static Schema CreateModelInfoSchema()
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema != null)
			{
				return schema;
			}
			SchemaBuilder schemaBuilder = new SchemaBuilder(ExtensibleStorageManager.ModelInfoGuid);
			schemaBuilder.SetSchemaName("ModelInfo");
			schemaBuilder.AddSimpleField("IsPipe", typeof(bool));
			schemaBuilder.AddSimpleField("ModelId", typeof(int));
			schemaBuilder.AddSimpleField("ViewId", typeof(int));
			schemaBuilder.AddSimpleField("LinkId0", typeof(int));
			schemaBuilder.AddSimpleField("LinkId1", typeof(int));
			schemaBuilder.AddSimpleField("LinkId2", typeof(int));
			schemaBuilder.AddSimpleField("DetailGroups", typeof(string));
			return schemaBuilder.Finish();
		}

		internal static void WriteDetailGroupsInfo(Element elem, string detailGoups)
		{
			Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
			Entity entity = elem.GetEntity(schema);
			Field field = schema.GetField("DetailGroups");
			if (field != null && entity != null)
			{
				entity.Set<string>(field, detailGoups);
				elem.SetEntity(entity);
			}
		}

		internal static string ReadDetailGroupsInfo(Element elem)
		{
			string result = string.Empty;
			Schema schema = ExtensibleStorageManager.CreateModelInfoSchema();
			Entity entity = elem.GetEntity(schema);
			Field field = schema.GetField("DetailGroups");
			if (field != null && entity != null)
			{
				result = entity.Get<string>(field);
			}
			return result;
		}

		internal static void WriteModelInfo(Element elem, bool isPipe, ElementId viewId, ElementId modelId)
		{
			Entity entity = new Entity(ExtensibleStorageManager.CreateModelInfoSchema());
			entity.Set<bool>("IsPipe", isPipe);
			entity.Set<int>("ViewId", viewId.IntegerValue);
			entity.Set<int>("ModelId", modelId.IntegerValue);
			elem.SetEntity(entity);
		}

		internal static void WriteModelInfo(Element elem, bool isPipe, ElementId viewId, ElementId modelId, List<ElementId> linkdeModelIds)
		{
			try
			{
				if (elem != null)
				{
					Entity entity = new Entity(ExtensibleStorageManager.CreateModelInfoSchema());
					entity.Set<bool>("IsPipe", isPipe);
					entity.Set<int>("ViewId", viewId.IntegerValue);
					entity.Set<int>("ModelId", modelId.IntegerValue);
					if (linkdeModelIds.Count > 0)
					{
						entity.Set<int>("LinkId0", linkdeModelIds[0].IntegerValue);
					}
					if (linkdeModelIds.Count > 1)
					{
						entity.Set<int>("LinkId1", linkdeModelIds[1].IntegerValue);
					}
					if (linkdeModelIds.Count > 2)
					{
						entity.Set<int>("LinkId2", linkdeModelIds[2].IntegerValue);
					}
					elem.SetEntity(entity);
				}
			}
			catch
			{
			}
		}

		internal static bool GetModelInfo(this Element elem, out bool isPipe, out ElementId modelId, out IEnumerable<ElementId> linkdeModelIds)
		{
			isPipe = false;
			modelId = ElementId.InvalidElementId;
			linkdeModelIds = Enumerable.Empty<ElementId>();
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return false;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return false;
			}
			isPipe = entity.Get<bool>("IsPipe");
			modelId = new ElementId(entity.Get<int>("ModelId"));
			linkdeModelIds = from eId in new ElementId[]
			{
				new ElementId(entity.Get<int>("LinkId0")),
				new ElementId(entity.Get<int>("LinkId1")),
				new ElementId(entity.Get<int>("LinkId2"))
			}
			where eId != ElementId.InvalidElementId
			select eId;
			return true;
		}

		internal static IEnumerable<ElementId> GetLinkedModelIds(Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return null;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return null;
			}
			return from eId in new ElementId[]
			{
				new ElementId(entity.Get<int>("LinkId0")),
				new ElementId(entity.Get<int>("LinkId1")),
				new ElementId(entity.Get<int>("LinkId2"))
			}
			where eId != ElementId.InvalidElementId
			select eId;
		}

		internal static bool HasModelSchema(this Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return false;
			}
			Entity entity = elem.GetEntity(schema);
			return entity.Schema != null;
		}

		internal static ElementId GetViewId(this Element elem)
		{
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return ElementId.InvalidElementId;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return ElementId.InvalidElementId;
			}
			return new ElementId(entity.Get<int>("ViewId"));
		}

		internal static ElementId GetModelId(this Element elem)
		{
			ElementId invalidElementId = ElementId.InvalidElementId;
			Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
			if (schema == null)
			{
				return invalidElementId;
			}
			Entity entity = elem.GetEntity(schema);
			if (entity.Schema == null)
			{
				return invalidElementId;
			}
			return new ElementId(entity.Get<int>("ModelId"));
		}

        //[return: Dynamic]
		internal static dynamic GetViewAndModelId(this Element elem)
		{
			object obj = new ExpandoObject();
            //if (ExtensibleStorageManager.<>o__17.<>p__0 == null)
            //{
            //    ExtensibleStorageManager.<>o__17.<>p__0 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<>o__17.<>p__0.Target(ExtensibleStorageManager.<>o__17.<>p__0, obj, ElementId.InvalidElementId);
            //if (ExtensibleStorageManager.<>o__17.<>p__1 == null)
            //{
            //    ExtensibleStorageManager.<>o__17.<>p__1 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<>o__17.<>p__1.Target(ExtensibleStorageManager.<>o__17.<>p__1, obj, ElementId.InvalidElementId);
            //Schema schema = Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid);
            //if (schema == null)
            //{
            //    return obj;
            //}
            //Entity entity = elem.GetEntity(schema);
            //if (entity.Schema == null)
            //{
            //    return obj;
            //}
            //if (ExtensibleStorageManager.<>o__17.<>p__2 == null)
            //{
            //    ExtensibleStorageManager.<>o__17.<>p__2 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<>o__17.<>p__2.Target(ExtensibleStorageManager.<>o__17.<>p__2, obj, new ElementId(entity.Get<int>("ViewId")));
            //if (ExtensibleStorageManager.<>o__17.<>p__3 == null)
            //{
            //    ExtensibleStorageManager.<>o__17.<>p__3 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //    {
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //    }));
            //}
            //ExtensibleStorageManager.<>o__17.<>p__3.Target(ExtensibleStorageManager.<>o__17.<>p__3, obj, new ElementId(entity.Get<int>("ModelId")));
			return obj;
		}

		internal static IEnumerable<Element> GetElementsByView(this Document doc, Autodesk.Revit.DB.View detailView)
		{
			if (Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid) == null)
			{
				return Enumerable.Empty<Element>();
			}
			ElementClassFilter item = new ElementClassFilter(typeof(CurveElement));
			ElementClassFilter item2 = new ElementClassFilter(typeof(TextNote));
			ElementClassFilter item3 = new ElementClassFilter(typeof(FilledRegion));
			LogicalOrFilter logicalOrFilter = new LogicalOrFilter(new List<ElementFilter>
			{
				item,
				item2,
				item3
			});
			return from elem in new FilteredElementCollector(doc).WherePasses(logicalOrFilter).ToElements()
			where detailView.Id == elem.GetViewId()
			select elem;
		}

		internal static IEnumerable<Element> GetElementsByModelId(this Document doc, Autodesk.Revit.DB.View View, ElementId modelId)
		{
            //if (Schema.Lookup(ExtensibleStorageManager.ModelInfoGuid) == null)
            //{
				return Enumerable.Empty<Element>();
			//}
            //ElementClassFilter item = new ElementClassFilter(typeof(CurveElement));
            //ElementClassFilter item2 = new ElementClassFilter(typeof(TextNote));
            //ElementClassFilter item3 = new ElementClassFilter(typeof(FilledRegion));
            //LogicalOrFilter logicalOrFilter = new LogicalOrFilter(new List<ElementFilter>
            //{
            //    item,
            //    item2,
            //    item3
            //});
            //return from <>h__TransparentIdentifier0 in new FilteredElementCollector(doc).WherePasses(logicalOrFilter).ToElements().Select(delegate(Element elem)
            //{
            //    if (ExtensibleStorageManager.<>o__19.<>p__0 == null)
            //    {
            //        ExtensibleStorageManager.<>o__19.<>p__0 = CallSite<Func<CallSite, Type, Element, object, <>f__AnonymousType2<Element, object>>>.Create(Binder.InvokeConstructor(CSharpBinderFlags.None, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType | CSharpArgumentInfoFlags.IsStaticType, null),
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null),
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //        }));
            //    }
            //    return ExtensibleStorageManager.<>o__19.<>p__0.Target(ExtensibleStorageManager.<>o__19.<>p__0, typeof(<>f__AnonymousType2<Element, object>), elem, elem.GetViewAndModelId());
            //}).Where(delegate(<>h__TransparentIdentifier0)
            //{
            //    if (ExtensibleStorageManager.<>o__19.<>p__7 == null)
            //    {
            //        ExtensibleStorageManager.<>o__19.<>p__7 = CallSite<Func<CallSite, object, bool>>.Create(Binder.Convert(CSharpBinderFlags.None, typeof(bool), typeof(ExtensibleStorageManager)));
            //    }
            //    Func<CallSite, object, bool> target = ExtensibleStorageManager.<>o__19.<>p__7.Target;
            //    CallSite <>p__ = ExtensibleStorageManager.<>o__19.<>p__7;
            //    if (ExtensibleStorageManager.<>o__19.<>p__2 == null)
            //    {
            //        ExtensibleStorageManager.<>o__19.<>p__2 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.Equal, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //        }));
            //    }
            //    Func<CallSite, object, ElementId, object> target2 = ExtensibleStorageManager.<>o__19.<>p__2.Target;
            //    CallSite <>p__2 = ExtensibleStorageManager.<>o__19.<>p__2;
            //    if (ExtensibleStorageManager.<>o__19.<>p__1 == null)
            //    {
            //        ExtensibleStorageManager.<>o__19.<>p__1 = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, "ViewId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //        }));
            //    }
            //    object obj = target2(<>p__2, ExtensibleStorageManager.<>o__19.<>p__1.Target(ExtensibleStorageManager.<>o__19.<>p__1, <>h__TransparentIdentifier0.info), Autodesk.Revit.DB.View.Id);
            //    if (ExtensibleStorageManager.<>o__19.<>p__6 == null)
            //    {
            //        ExtensibleStorageManager.<>o__19.<>p__6 = CallSite<Func<CallSite, object, bool>>.Create(Binder.UnaryOperation(CSharpBinderFlags.None, ExpressionType.IsFalse, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //        {
            //            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //        }));
            //    }
            //    object arg2;
            //    if (!ExtensibleStorageManager.<>o__19.<>p__6.Target(ExtensibleStorageManager.<>o__19.<>p__6, obj))
            //    {
            //        if (ExtensibleStorageManager.<>o__19.<>p__5 == null)
            //        {
            //            ExtensibleStorageManager.<>o__19.<>p__5 = CallSite<Func<CallSite, object, object, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.BinaryOperationLogical, ExpressionType.And, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //            }));
            //        }
            //        Func<CallSite, object, object, object> target3 = ExtensibleStorageManager.<>o__19.<>p__5.Target;
            //        CallSite <>p__3 = ExtensibleStorageManager.<>o__19.<>p__5;
            //        object arg = obj;
            //        if (ExtensibleStorageManager.<>o__19.<>p__4 == null)
            //        {
            //            ExtensibleStorageManager.<>o__19.<>p__4 = CallSite<Func<CallSite, object, ElementId, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.Equal, typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
            //            }));
            //        }
            //        Func<CallSite, object, ElementId, object> target4 = ExtensibleStorageManager.<>o__19.<>p__4.Target;
            //        CallSite <>p__4 = ExtensibleStorageManager.<>o__19.<>p__4;
            //        if (ExtensibleStorageManager.<>o__19.<>p__3 == null)
            //        {
            //            ExtensibleStorageManager.<>o__19.<>p__3 = CallSite<Func<CallSite, object, object>>.Create(Binder.GetMember(CSharpBinderFlags.None, "ModelId", typeof(ExtensibleStorageManager), new CSharpArgumentInfo[]
            //            {
            //                CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
            //            }));
            //        }
            //        arg2 = target3(<>p__3, arg, target4(<>p__4, ExtensibleStorageManager.<>o__19.<>p__3.Target(ExtensibleStorageManager.<>o__19.<>p__3, <>h__TransparentIdentifier0.info), modelId));
            //    }
            //    else
            //    {
            //        arg2 = obj;
            //    }
            //    return target(<>p__, arg2);
			}
       // )
            //select <>h__TransparentIdentifier0.elem;
		

		private static readonly Guid m_GUID = new Guid("406EB829-8264-42E9-A66F-685E5DA49189");

		private static readonly string m_schemaName = "HY_Plumbing_SystemDiagramNew_ESData";

		private static readonly Guid ModelInfoGuid = new Guid("{ACC0D869-C937-4B53-9F20-34BF313994E2}");
	}
}
